package com.xindao.photonics.fragments.manager;

import java.util.Stack;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentTransaction;

/**
 * fragment跳转管理器
 * 
 * @author chenghao
 * 
 */
final class FragmentManager {
    private final Object[] mObjects;
    private final int containerId;
    private final FragmentActivity mFragmentActivity;
    private final BaseFragment[] mFragments;

    /** 是否在切换tab时清空当前栈 */
    private boolean isClearStack;

    private int mCurrentTabId = -1;

    @SuppressWarnings("rawtypes")
    public FragmentManager(FragmentActivity fragmentActivity, Class[] mTabFragments, int containerId) {
        super();
        this.containerId = containerId;
        this.mFragmentActivity = fragmentActivity;

        if (null == mTabFragments) {
            mObjects = new Object[1];

            for (int i = 0; i < 1; i++) {
                mObjects[i] = new Stack<Fragment>();
            }

            mFragments = new BaseFragment[1];
        } else {
            mObjects = new Object[mTabFragments.length];
            for (int i = 0; i < mTabFragments.length; i++) {
                mObjects[i] = new Stack<Fragment>();
            }

            mFragments = new BaseFragment[mTabFragments.length];

            for (int i = 0; i < mTabFragments.length; i++) {
                try {
                    mFragments[i] = (BaseFragment) mTabFragments[i].newInstance();
                } catch (InstantiationException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 切换Tab，tabfragment会被缓存，暂不支持tab中跳转的fragment进行缓存，切换tab的时候清空当前栈
     */
    public void startTabFragment(Class<? extends BaseFragment> clzz) {
        int tabId = getTabId(clzz);

        if (mCurrentTabId == tabId) {
            return;
        }
        // 如果已经显示过了，则调用show
        FragmentTransaction transaction =
                mFragmentActivity.getSupportFragmentManager().beginTransaction();

        if (mCurrentTabId != -1) {
            // 获取之前tab的栈
            Stack<BaseFragment> oldStacks = (Stack<BaseFragment>) mObjects[mCurrentTabId];
            if (isClearStack) {
                // 删除栈，只保留第一个
                for (int i = oldStacks.size() - 1; i > 0; i--) {
                    transaction.remove(oldStacks.pop());
                    // oldStacks.remove(i);
                }
            }
            if (oldStacks.size() > 0) {
                transaction.hide(oldStacks.peek());
            }
        }

        mCurrentTabId = tabId;

        // 获取当前tab的栈
        Stack<BaseFragment> stack = (Stack<BaseFragment>) mObjects[tabId];

        if (stack.size() > 0) {
            transaction.show(mFragments[tabId]);
        } else {
            transaction.add(containerId, mFragments[tabId]);
            stack.add(mFragments[tabId]);
        }
        transaction.commit();
    }

    public void setClearStack(boolean isClearStack) {
        this.isClearStack = isClearStack;
    }

    private int getTabId(Class<? extends BaseFragment> clzz) {
        for (int i = 0; i < mFragments.length; i++) {
            if (mFragments[i].getClass().getSimpleName().equals(clzz.getSimpleName())) {
                return i;
            }
        }
        throw new RuntimeException(
                "The fragment is not a tab!! please use startfragment(Fragment fragment)");
    }

    /**
     * 清空栈前面的Fragment
     * 
     * @param fragment
     */
    public void startFragmentAndClearStack(BaseFragment fragment) {
        // 清空当前栈
        if (mCurrentTabId == -1) {
            mCurrentTabId = 0;
        }
        // Stack<BaseFragment> stack = (Stack<BaseFragment>) mObjects[mCurrentTabId];
        // stack.clear();

        // 如果已经显示过了，则调用show
        FragmentTransaction transaction =
                mFragmentActivity.getSupportFragmentManager().beginTransaction();

        // 获取之前tab的栈
        Stack<BaseFragment> oldStacks = (Stack<BaseFragment>) mObjects[mCurrentTabId];
        // 删除栈，只保留第一个
        for (int i = oldStacks.size() - 1; i >= 0; i--) {
            Fragment f = oldStacks.pop();
            transaction.hide(f);
            transaction.remove(f);
            // oldStacks.remove(i);
        }
        /*
         * if (oldStacks.size() > 0) { transaction.hide(oldStacks.peek()); }
         */
        transaction.commit();
        startFragment(fragment);
    }

    /**
     * 启动一个新的fragment，不支持缓存
     * 
     * @param fragment
     */
    public void startFragment(BaseFragment fragment) {
        FragmentTransaction transaction =
                mFragmentActivity.getSupportFragmentManager().beginTransaction();

        if (mCurrentTabId == -1) {
            mCurrentTabId = 0;
        }

        Stack<BaseFragment> stack = (Stack<BaseFragment>) mObjects[mCurrentTabId];

        if (getStackSize() > 0) {
            transaction.hide(stack.peek());
        }
        stack.add(fragment);
        transaction.add(containerId, fragment);
        transaction.commit();
    }

    public boolean isHasOtherOption() {
        Stack<BaseFragment> stack = (Stack<BaseFragment>) mObjects[mCurrentTabId];
        if (!stack.isEmpty() && stack.peek().handleOptions()) {
            return true;
        }
        return false;
    }

    /**
     * 后退 如果当前栈中数量为1，说明后退到tab页面，不可以继续后退，只能调用系统方法onBackPressed()
     */
    public boolean backFragment() {
        if (getStackSize() == 1) {
            return false;
        }
        Stack<BaseFragment> stack = (Stack<BaseFragment>) mObjects[mCurrentTabId];

        FragmentTransaction transaction =
                mFragmentActivity.getSupportFragmentManager().beginTransaction();

        BaseFragment topFragment = stack.pop();
        Bundle bundle = topFragment.getBundle();

        transaction.remove(topFragment);

        if (!stack.isEmpty()) {
            BaseFragment fragment = stack.peek();
            transaction.show(fragment);
            transaction.commit();
            if (null != bundle) {
                fragment.onFragmentResult(bundle);
            }
        }

        return true;
    }

    /*
     * public boolean backFragment() { return backFragment(null); }
     */

    /**
     * 获取当前栈中fragment的数量
     * 
     * @return
     */
    private int getStackSize() {
        Stack<Fragment> stack = (Stack<Fragment>) mObjects[mCurrentTabId];
        return stack.size();
    }

}
